/*
 * 文件名：PayServiceImpl.java
 * 版权：
 * 描述：TODO
 * 修改人：zuo liubo
 * 修改时间：2013-3-12 下午6:57:22
 */
package com.scpii.api.service.ec.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.scpii.api.common.EcConstants;
import com.scpii.api.common.EcConstants.PaymentType;
import com.scpii.api.common.exception.ClientException;
import com.scpii.api.common.exception.EcException;
import com.scpii.api.common.exception.UserIdDisaccordException;
import com.scpii.api.domain.ec.Order;
import com.scpii.api.domain.ec.OrderDetail;
import com.scpii.api.domain.ec.Product;
import com.scpii.api.domain.user.Users;
import com.scpii.api.persistence.ec.OrderMapper;
import com.scpii.api.persistence.ec.ProductMapper;
import com.scpii.api.persistence.user.UsersMapper;
import com.scpii.api.service.alipay.AlipayService;
import com.scpii.api.service.ec.PayService;
import com.scpii.api.util.ConvertionUtil;
import com.scpii.api.util.PrincipalUtil;

/**
 * @description TODO
 * @author zuo liubo
 * @date 2013-3-12
 */
@Service("payService")
public class PayServiceImpl implements PayService {

	@Resource
	private OrderMapper orderMapper;
	@Resource
	private ProductMapper productMapper;
	@Resource
	private UsersMapper usersMapper;
	
	@Resource
	private AlipayService alipayService;

	public Object payOrder(Long orderId) throws EcException{
		Long _userId = PrincipalUtil.getPrincipal().getId();
		return payOrder(orderId, _userId);
	}
	
	@Override
	public Object payOrder(Long orderId, Long userId) throws EcException {
		// 1.查询订单信息
		Order order = new Order();
		order.setOrderId(orderId);
		order.setOrderStatus(EcConstants.OrderStatus.CONFIRMED);
		order.setPayStatus(EcConstants.PayStatus.PAYMENT_NONE);
		List<Order> orderList = orderMapper.selectOrderBySelective(order);
		if (orderList.size() != 1) {
			throw new EcException(EcConstants.ERROR_INFO.ORDER_ID_ERROR);
		}
		order = orderList.get(0);
		if(!userId.equals(order.getUserId())){
			throw new UserIdDisaccordException();
		}

		String alipayURL = null;
		// 根据支付方式判断如何进行支付
		switch (order.getPaymentType()) {
		case PaymentType.PAY_ONLINE:
			alipayURL = alipayService.pay(order);
			break;
		case PaymentType.PAY_POINT:
			pay4Point(order,userId);
			break;
		case PaymentType.PAY_CASH:
			//货到付款-->不做任何处理
			break;
		default:
			 throw new EcException(EcConstants.ERROR_INFO.PAYMENTINFO_ERROR); 
		}
		
		Map<String,Object> map = new HashMap<String, Object>();
		map.put("orderId", order.getOrderId());
		map.put("orderSn", order.getOrderSn());
		map.put("paymentType", order.getPaymentType());
		map.put("alipayURL", alipayURL);
		map.put("status", 2000);
		map.put("statusDescription", "支付成功");
		if(order.getPaymentType() == EcConstants.PaymentType.PAY_CASH){
			map.put("statusDescription", "货到付款提交成功");
		}
		map.put("totalPrice", order.getTotalPrice());
		return map;
		
		
	}
	
	/**
	 * 更新产品信息（减少库存量  增加订单量  赠送积分）
	 * @param order	订单信息
	 */
	public void updateInfo(Order order){
		int points = 0;
		for ( OrderDetail  od : order.getOrderDetails()){
			Product product = new Product();
			int quantity = od.getQuantity();
			product.setProductId(od.getProduct().getProductId());
			product = productMapper.selectBySelective(product).get(0);
			product.setStoreQuantity(ConvertionUtil.convertInteger(product.getStoreQuantity()) - quantity);
			product.setOrderCount(ConvertionUtil.convertInteger(product.getOrderCount()) + quantity);
			productMapper.updateByPrimaryKeySelective(product);
			points = points + ConvertionUtil.convertInteger(product.getGiveUserPoints()) * quantity;
		}
		
		Users users = usersMapper.selectByPrimaryKey(order.getUserId());
		users.setRankPoint(ConvertionUtil.convertInteger(users.getRankPoint()) + points);
		usersMapper.updateByPrimaryKey(users);
	}
	

	/**
	 * 使用积分支付订单
	 * @param order	订单对象
	 * @param userId	用户ID
	 * @return	返回支付信息
	 */
	private Object pay4Point(Order order, Long userId) throws ClientException {
		Users users = usersMapper.selectByPrimaryKey(userId);
		int orderPrice = (int)((float) order.getTotalPrice());
		
		int rankPoint = ConvertionUtil.convertInteger(users.getRankPoint());
		if(rankPoint < orderPrice){
			throw new EcException(EcConstants.ERROR_INFO.POINTS_BALANCE_NOT_ENOUGH);
		}
		synchronized (users) {
			users.setRankPoint(rankPoint - orderPrice);
			usersMapper.updateByPrimaryKeySelective(users);
		}
		updateGiveUserPoints(order);
		updatePayStatus(order.getOrderId(), EcConstants.PayStatus.PAYMENT_SUCCESS);
		return true;
	}
	
	/**
	 * 更新订单的支付信息
	 * @param orderId 订单ID
	 * @param payStatus	支付状态
	 */
	private void updatePayStatus(Long orderId,int payStatus){
		Order _order = new Order();
		_order.setOrderId(orderId);
		_order.setPayStatus(payStatus);
		orderMapper.updateByPrimaryKeySelective(_order);
	}

	@Override
	public void updateGiveUserPoints(Order order) {
		int points = 0;
		for ( OrderDetail  od : order.getOrderDetails()){
			Product product = new Product();
			int quantity = od.getQuantity();
			product.setProductId(od.getProduct().getProductId());
			product = productMapper.selectBySelective(product).get(0);
			points = points + ConvertionUtil.convertInteger(product.getGiveUserPoints()) * quantity;
		}
		
		Users users = usersMapper.selectByPrimaryKey(order.getUserId());
		users.setRankPoint(ConvertionUtil.convertInteger(users.getRankPoint()) + points);
		usersMapper.updateByPrimaryKey(users);
		
	}

	@Override
	public void updateStoreQuantityAndOrderCount(Order order,boolean type) {
		for ( OrderDetail  od : order.getOrderDetails()){
			Product product = new Product();
			int quantity = od.getQuantity();
			product.setProductId(od.getProduct().getProductId());
			product = productMapper.selectBySelective(product).get(0);
			if(type){
				product.setStoreQuantity(ConvertionUtil.convertInteger(product.getStoreQuantity()) - quantity);
				product.setOrderCount(ConvertionUtil.convertInteger(product.getOrderCount()) + quantity);
			}else{
				product.setStoreQuantity(ConvertionUtil.convertInteger(product.getStoreQuantity()) + quantity);
				product.setOrderCount(ConvertionUtil.convertInteger(product.getOrderCount()) - quantity);
			}
			productMapper.updateByPrimaryKeySelective(product);
		}
	}
}
